package administracion;

import java.util.ArrayList;
import java.util.List;

import dao.ComandaDAO;
import dao.MesaDAO;
import dao.MozoDAO;
import dao.SectorDAO;
import dto.EmpleadoDTO;
import dto.MesaDTO;
import dto.MesaSimpleDTO;
import dto.MozoDTO;
import dto.PlatoDTO;
import dto.SectorDTO;
import entity.Comanda;
import entity.Mesa;
import entity.MesaCompuesta;
import entity.MesaSimple;
import entity.Mozo;

public class MesaManager {
	private static MesaManager instancia;
	private MesaDAO dao = MesaDAO.getInstancia();
	
	private MesaManager() {
			
	}
	
	public static MesaManager getInstancia(){
		if(instancia == null)
			instancia = new MesaManager();
		return instancia;
	}


	public List<MesaDTO> listarMesasLibresPorSector(SectorDTO sector, int cantComensales) {
		
		List<MesaDTO> result=new ArrayList<MesaDTO>();
		
		//Valida Sector
		SectorManager.getInstancia().buscarSector(sector);
		
		//Buscar Mesas disponibles
		List<MesaSimple> mesasSimples= dao.listarMesasLibresPorSector(sector.getIdSector());
	
		if (mesasSimples != null) {
			for(MesaSimple ms:mesasSimples){
				if (ms.getCapacidad()>=cantComensales){
					result.add(ms.getDTO());
				}
			}
		}
		
		return result;
	}
	
	public List<MesaDTO> armarMesaCompuesta(SectorDTO sector, int cantComensales) {
		
		List<MesaDTO> result=new ArrayList<MesaDTO>();
		
		//Valida Sector
		SectorManager.getInstancia().buscarSector(sector);
		
		//Buscar Mesas disponibles
		List<MesaSimple> mesasSimples= dao.listarMesasLibresPorSector(sector.getIdSector());
		
		List<MesaSimple> posibles= unirMesas(mesasSimples,cantComensales);
	
		if (posibles != null) {
			for(MesaSimple ms:posibles){
				result.add(ms.getDTO());
			}
		}
		
		return result;
	}
	
	private List<MesaSimple> unirMesas(List<MesaSimple> mesas, int cantComensales){
		
		for(MesaSimple ms:mesas){
			int cont=0;
			List<MesaSimple> aux=new ArrayList<MesaSimple>();
			
			cont=cont+ms.getCapacidad();
			aux.add(ms);
			List<MesaSimple> vecinos=ms.getVecinos();
			for(MesaSimple vecino:vecinos){
				if (cont<cantComensales && vecino.getEstado().equalsIgnoreCase("libre")){
					cont=cont+vecino.getCapacidad();
					aux.add(vecino);
				}
			}
			
			if (cont>=cantComensales){
				return aux;
			}

		}
		return null;
		
	}

	//Apertura Mesa Simple
	public boolean abrirMesaSimpl(MesaSimpleDTO mesaDto, MozoDTO mozoDto){

		MesaSimple mesaSimp = (MesaSimple) dao.buscarMesa(mesaDto.getIdMesa());
		Mozo mozo = MozoDAO.getInstancia().buscarMozoCodigo(mozoDto.getLegajo());
		
		//Asocia comanda sin items a instancia de Mesa
		Comanda comanda=new Comanda();
		comanda.setMesa(mesaSimp);
		comanda.setMozo(mozo);
		comanda.setEstado("pendiente");
		comanda.setItems(null);
		
		
		ComandaDAO.getInstancia().save(comanda);
		
		Comanda c = ComandaDAO.getInstancia().buscarComandaMesa(mesaSimp);
		
		mesaSimp.setComanda(c);
		mesaSimp.setEstado("ocupada");
		
		dao.mergeMesa(mesaSimp);
		
		return true;
		
	}
	
	//Apertura Mesa Compuesta
	public MesaDTO abrirMesaComp(List<MesaSimpleDTO> mesas, MozoDTO mozoDto){
			
		//Obtiene el mayor numero de mesa	
		int numMesaComp=0;
		for (MesaSimpleDTO ms:mesas){
			if (ms.getNumero()>numMesaComp){
				numMesaComp=ms.getNumero();
			}
		}
			
		//Crea instancia de mesa compuesta	
		MesaCompuesta mesaComp = new MesaCompuesta();
//		mesaComp.setIdMesa(mesaDto.getIdMesa());
		mesaComp.setNumero(numMesaComp);
		dao.altaMesa(mesaComp);
			
		//Actualiza el estado de cada mesa componente
		List<MesaSimple> listaMS = new ArrayList<MesaSimple>();
		for(MesaSimpleDTO mList:mesas){
			MesaSimple mesaSimp= (MesaSimple) dao.buscarMesa(mList.getIdMesa());
			mesaSimp.setEstado("ocupada");
			dao.mergeMesa(mesaSimp);
				
			listaMS.add(mesaSimp);
		}
			
		//Asocia mesas componentes
		mesaComp.setComponentes(listaMS);
		
		//Asocia comanda sin items a instancia de Mesa
		Mozo mozo=MozoDAO.getInstancia().buscarMozoCodigo(mozoDto.getLegajo());
		Comanda comanda=new Comanda();
		comanda.setMesa(mesaComp);
		comanda.setMozo(mozo);
		comanda.setEstado("pendiente");
		comanda.setItems(null);
		mesaComp.setComanda(comanda);
					
		dao.mergeMesa(mesaComp);
		
		return mesaComp.getDTO();
	}
	
	//Cierre Mesa Simple
	public boolean cerrarMesaSimpl(MesaDTO mesa, EmpleadoDTO emp){
		MesaSimple m = MesaDAO.getInstancia().buscarMesa(mesa.getIdMesa());
		Mozo mozo = MozoDAO.getInstancia().buscarMozoCodigo(emp.getLegajo());
		List<MesaSimple> asignadas = new ArrayList<MesaSimple>();
		
		//Desvinculo esa mesa del mozo
		for(MesaSimple mes: mozo.getMesasAsignadas()){
			if(mes.getIdMesa() != m.getIdMesa())
				asignadas.add(mes);
		}
		
		mozo.setMesasAsignadas(asignadas);
		
		//update mozo
		MozoDAO.getInstancia().updateMozo(mozo);
		
		//Seteo la comanda como completa
		m.getComanda().setEstado("completa");
		
		ComandaDAO.getInstancia().updateComanda(m.getComanda());
		
		//Desvinculo la comanda de la mesa
		m.setComanda(null);
		//Seteo la mesa como libre
		m.setEstado("libre");
		//seteo que la mesa esta facturada
		m.setFacturada(false);
		
		MesaDAO.getInstancia().mergeMesa(m);
		
		return true;
		
		
	}
		
	//Cierre Mesa Compuesta
	public void cerrarMesaComp(MesaDTO mesa){
		
	
	}	
	
	public Mesa buscarMesaNombre(MesaDTO mes) {
		return MesaDAO.getInstancia().buscarMesa(mes.getIdMesa());
		
	}

}
